package com.panopset.centralen.util;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * From http://www.whatsabyte.com/.
 *
 * Processor or Virtual Storage: 1 Bit = Binary Digit 8 Bits = 1 Byte 1024 Bytes
 * = 1 Kilobyte 1024 Kilobytes = 1 Megabyte 1024 Megabytes = 1 Gigabyte 1024
 * Gigabytes = 1 Terabyte 1024 Terabytes = 1 Petabyte 1024 Petabytes = 1 Exabyte
 * 1024 Exabytes = 1 Zettabyte 1024 Zettabytes = 1 Yottabyte 1024 Yottabytes = 1
 * Brontobyte 1024 Brontobytes = 1 Geopbyte
 *
 * Disk Storage: 1 Bit = Binary Digit 8 Bits = 1 Byte 1000 Bytes = 1 Kilobyte
 * 1000 Kilobytes = 1 Megabyte 1000 Megabytes = 1 Gigabyte 1000 Gigabytes = 1
 * Terabyte 1000 Terabytes = 1 Petabyte 1000 Petabytes = 1 Exabyte 1000 Exabytes
 * = 1 Zettabyte 1000 Zettabytes = 1 Yottabyte 1000 Yottabytes = 1 Brontobyte
 * 1000 Brontobytes = 1 Geopbyte
 *
 */
public final class Measures {

    /**
     * Names.
     */
    public static final String[] NAMES = new String[] {"", "kilo", "mega",
            "giga", "tera", "peta", "exa", "zetta", "yotta", "bronto", "geop" };

    /**
     * 1000.
     */
    public static final int DISK_MEASURE = 1000;

    /**
     * 1024.
     */
    public static final int MEMORY_MEASURE = 1024;

    /**
     * 3.
     */
    private static final int PRECISION = 1;

    /**
     * @param bytes
     *            Bytes.
     * @param size
     *            Notation size, 1024 or 1000.
     * @return Easily readable measurement.
     */
    private static String getNotationFor(final long bytes, final int size) {
        long x = size;
        int step = 0;
        long d = 1;
        while (x < bytes && step++ < NAMES.length) {
            x = x * size;
            d = d * size;
        }
        BigDecimal avail = new BigDecimal(bytes);
        avail = avail.divide(new BigDecimal("" + d), PRECISION,
                    RoundingMode.HALF_UP);
        return "" + avail + " " + NAMES[step] + "bytes";
    }

    /**
     * @param bytes Bytes.
     * @return Notation in bytes x 1000.
     */
    public static String getDiskNotationFor(final long bytes) {
        return getNotationFor(bytes, DISK_MEASURE);
    }

    /**
     * @param bytes Bytes.
     * @return Notation in bytes x 1024.
     */
    public static String getMemoryNotationFor(final long bytes) {
        return getNotationFor(bytes, MEMORY_MEASURE);
    }

    /**
     * Prevent instantiation.
     */
    private Measures() {
    }
}
